package demo;

import cn.hutool.core.util.ArrayUtil;
import demo.util.SerialPortUtils;
import gnu.io.SerialPort;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class SerialPortTest {

    private static ArrayList<List<Byte>> receiveList = new ArrayList<>();

    private static Map<String, Group> map = new LinkedHashMap<>();

    private static int count = 0;

    private static int readCount = 0;

    private static Divide divide;

    private static class Divide {
        private final byte leadLow;
        private final byte leadHigh;
        private final byte zeroLow;
        private final byte zeroHigh;
        private final byte oneLow;
        private final byte oneHigh;

        public Divide(byte leadLow, byte leadHigh, byte zeroLow, byte zeroHigh, byte oneLow, byte oneHigh) {
            this.leadLow = leadLow;
            this.leadHigh = leadHigh;
            this.zeroLow = zeroLow;
            this.zeroHigh = zeroHigh;
            this.oneLow = oneLow;
            this.oneHigh = oneHigh;
        }


        @Override
        public String toString() {
            return "Divide{" +
                    "leadLow=" + leadLow +
                    ", leadHigh=" + leadHigh +
                    ", zeroLow=" + zeroLow +
                    ", zeroHigh=" + zeroHigh +
                    ", oneLow=" + oneLow +
                    ", oneHigh=" + oneHigh +
                    '}';
        }


    }

    private static class Group {
        private final String value;

        @Override
        public String toString() {
            String str = "";
            for (List<Byte> x : list) {
                str = getValue(x) + "\n";
            }
            return str;
        }

        private List<List<Byte>> list;

        public Group(String value) {
            this.value = value;
        }

        public void addItem(List<Byte> item) {
            list.add(item);
        }

        public void sub(int index) {
            List<List<Byte>> newList = new ArrayList<>();
            int first = list.get(0).size() - index;
            list = list.subList(0, first);
            for (List<Byte> x : list) {
                x = x.subList(0, first);
                newList.add(x);
            }
            list = newList;
        }
    }

    public static void copy(byte[] data, List<Byte> resultList) {
        for (byte datum : data) {
            if (datum > 60) {
                resultList.add(datum);
            } else if (datum < 8) {
                resultList.add((byte) 0);
            } else if (datum > 8 && datum < 15) {
                resultList.add((byte) 1);
            }
        }
    }

    public static void getMap() {
        for (int i = 0; i < receiveList.size(); i++) {
            List<Byte> flash = receiveList.get(i);
            String value = getValue(flash);
            if (ArrayUtil.isEmpty(map.get(value))) {
                Group group = new Group(value);
                group.addItem(flash);
                map.put(value, group);
            } else {
                Group group = map.get(value);
                group.addItem(flash);
                map.put(value, group);
            }
        }
    }

    public static int getMaxLength() {
        int min = Integer.MAX_VALUE;
        for (String x : map.keySet()) {
            int index0 = x.indexOf("1");
            int index1 = x.indexOf("_");
            int index = Math.min(index0, index1);
            if (index < min) {
                min = index;
            }
        }
        return min;
    }

    public static void getFinalMap(int index) {
        Map<String, Group> newMap = new LinkedHashMap<>();
        for (String x : map.keySet()) {
            String key = x.substring(index - 1);
            Group group = map.get(x);
            group.sub(index);
            newMap.put(key, group);
        }
        map = newMap;
    }

    public static String getValue(List<Byte> flash) {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < flash.size(); i++) {
            byte b = flash.get(i);
            if (i == (byte) 0 || i == (byte) 1) {
                str.insert(0, String.valueOf(b));
            } else {
                str.insert(0, "_");
            }
        }
        return str.toString();
    }

    public static void getResultData(byte[] data) {

        if (data.length == 200) {
            int i = 0;
            for (i = 0; i < 20; i++) {
                byte[] data0 = new byte[100];
                System.arraycopy(data, 0, data0, 0, data0.length);
                ArrayList<Byte> flash = new ArrayList<Byte>();
                copy(data0, flash);
                receiveList.add(flash);
            }
            if (i == 40) {
                getMap();
                int index = getMaxLength();
                getFinalMap(index);
            } else {
                printfMap();
            }
        }
    }

    public static void printfMap() {
        for (String key : map.keySet()) {
            System.out.println(key);
            Group group = map.get(key);
            System.out.println(group);
        }
    }

    public static void main(String[] args) {


        // 打开串口
        SerialPort serialPort = SerialPortUtils.open("COM3", 9600, SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

        // 监听串口读取数据
        SerialPortUtils.addListener(serialPort, () -> {
            byte[] data = SerialPortUtils.read(serialPort);
            List<Byte> byteList = new ArrayList<>();
            for (int i = 0; i < data.length; i++) {
                if (data[i] != 0) {
                    byteList.add(data[i]);
                    System.out.print(data[i] + " ");
                }
            }

            getResultData(data);
            System.out.println();
        });

//        byte[] data = {66,
//                5,6,5,6,5,6,11,5,
//                11,11,11,11,11,11,6,11,
//                5,11,6,5,11,5,6,6,
//                11,5,11,11,5,11,11,11,
//                11,6};
//        byte[] data = {
//                0,0,0,0,0,0,1,0,
//                1,1,1,1,1,1,0,1,
//                0,1,0,0,1,0,0,0,
//                1,0,1,1,0,1,1,1,
//                1,0};
//        SerialPortUtils.write(serialPort, data);
//        // 往串口发送数据
//        byte[] data = {1, 2, 3};
//        SerialPortUtils.write(serialPort, data);

        /*// 关闭串口
        Thread.sleep(2000);
        SerialPortUtils.close(serialPort);*/

        // 测试可用端口
        //SerialPortUtils.listPortName().forEach(o -> System.out.println(o));
    }
}
